package com.qumitech.visualnovel.controller.rest;

import com.qumitech.visualnovel.console.excel.ExportExcel;
import com.qumitech.visualnovel.console.excel.StateField;
import com.qumitech.visualnovel.console.excel.State;
import com.qumitech.visualnovel.console.excel.UnitField;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.ResultEnum;
import com.qumitech.visualnovel.pubdef.dto.skill.*;
import com.qumitech.visualnovel.pubdef.pubenum.GodRestrictStateEnum;
import com.qumitech.visualnovel.pubdef.pubenum.GodStateEnum;
import com.qumitech.visualnovel.pubdef.pubenum.SkillForbidFlagEnum;
import com.qumitech.visualnovel.service.skill.SkillService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

import static com.qumitech.visualnovel.service.skill.constant.SkillConstant.authCategory;
import static com.qumitech.visualnovel.service.skill.constant.SkillConstant.orderCategory;

/**
 * @author ywxie
 * @date 2020/1/14 10:30
 * @description
 */
@RestController
@RequestMapping("/api/skill")
public class SkillController {

    @Autowired
    private SkillService skillService;

    @GetMapping("config")
    public BaseRsp listSkillConfig(){
        return skillService.listSkillConfig();
    }

    @RequiresPermissions("skillVerifyList:view")
    @GetMapping("/verify")
    public BaseRsp listSkillVerifyAdmin(@RequestParam(value = "limit", required = false, defaultValue = "20") String limit,
                                  @RequestParam(value = "offset", required = false, defaultValue = "0") String offset,
                                  @RequestParam(value = "uid", required = false) String uid,
                                  @RequestParam(value = "category", required = false) String category,
                                  @RequestParam(value = "verify_type", required = false) String verifyType,
                                  @RequestParam(value = "skill_id", required = false) String skillId,
                                  @RequestParam(value = "admin_state", required = false) String state,
                                  @RequestParam(value = "startTime", required = false) String startTime,
                                  @RequestParam(value = "endTime", required = false) String endTime){
        Map<String, String> paramMap = getGeneralParamMap(limit, offset, uid, startTime, endTime);
        if(category != null){
            paramMap.put("category", category);
        }
        if(verifyType != null){
            paramMap.put("verify_type", verifyType);
        }
        if(skillId != null){
            paramMap.put("skill_id", skillId);
        }
        if(state != null){
            paramMap.put("admin_state", state);
        }
        return skillService.listSkillVerifyAdmin(paramMap);
    }

    @PutMapping("/verify")
    public BaseRsp updateSkillVerifyAdmin(@RequestBody SkillVerifyAdminUpdateDTO updateDTO){
        return skillService.updateSkillVerifyAdmin(updateDTO);
    }

    @RequiresPermissions("skillList:view")
    @GetMapping("/user/skill")
    @ExportExcel(itemCls = SkillAdminExportDTO.class,
            listKey = "skill_admin_list",
            stateFields = {
                    @StateField(key="sex", states = {
                            @State(state="0", display = "女"),
                            @State(state = "1", display = "男")
                    }),
                    @StateField(key="category", states = {
                            @State(state="0", display = "音乐"),
                            @State(state = "1", display = "游戏")
                    }),
                    @StateField(key="mainFlag", states = {
                            @State(state="0", display = "否"),
                            @State(state = "1", display = "是")
                    }),
                    @StateField(key="openFlag", states = {
                            @State(state="0", display = "关闭接单"),
                            @State(state="1", display = "开启接单"),
                    }),
                    @StateField(key="topType", states = {
                            @State(state="0", display = "否"),
                            @State(state="1", display = "是")
                    }),
                    @StateField(key="forbidFlag", states = {
                            @State(state="0", display = "未禁止"),
                            @State(state="1", display = "已禁止")
                    })
            }
    )
    public BaseRsp listUserSkillAdmin(@RequestParam(value = "limit", required = false, defaultValue = "20") String limit,
                                      @RequestParam(value = "offset", required = false, defaultValue = "0") String offset,
                                      @RequestParam(value = "uid", required = false) String uid,
                                      @RequestParam(value = "user_name", required = false) String userName,
                                      @RequestParam(value = "sex", required = false) String sex,
                                      @RequestParam(value = "category", required = false) String category,
                                      @RequestParam(value = "skill_id", required = false) String skillId,
                                      @RequestParam(value = "main_flag", required = false) String mainFlag,
                                      @RequestParam(value = "open_flag", required = false) String openFlag,
                                      @RequestParam(value = "forbid_flag", required = false) String forbidFlag,
                                      @RequestParam(value = "startTime", required = false) String startTime,
                                      @RequestParam(value = "endTime", required = false) String endTime){
        Map<String, String> paramMap = getGeneralParamMap(limit, offset, uid, startTime, endTime);
        if (userName != null){
            paramMap.put("user_name", userName);
        }
        if(sex != null){
            paramMap.put("sex", sex);
        }
        if(category != null){
            paramMap.put("category", category);
        }
        if(mainFlag != null){
            paramMap.put("main_flag", mainFlag);
        }
        if(openFlag != null){
            paramMap.put("open_flag", openFlag);
        }
        if(skillId != null){
            paramMap.put("skill_id", skillId);
        }
        if(forbidFlag != null){
            paramMap.put("forbid_flag", forbidFlag);
        }
        return skillService.listUserSkillAdmin(paramMap);
    }

    @RequestMapping(value = "/user/skill/export", method = RequestMethod.POST)
    public BaseRsp listUserSkillAdminExport(@RequestParam(value = "limit", required = false, defaultValue = "20") String limit,
                                            @RequestParam(value = "offset", required = false, defaultValue = "0") String offset,
                                            @RequestParam(value = "uid", required = false) String uid,
                                            @RequestParam(value = "user_name", required = false) String userName,
                                            @RequestParam(value = "sex", required = false) String sex,
                                            @RequestParam(value = "category", required = false) String category,
                                            @RequestParam(value = "skill_id", required = false) String skillId,
                                            @RequestParam(value = "main_flag", required = false) String mainFlag,
                                            @RequestParam(value = "open_flag", required = false) String openFlag,
                                            @RequestParam(value = "forbid_flag", required = false) String forbidFlag,
                                            @RequestParam(value = "startTime", required = false) String startTime,
                                            @RequestParam(value = "endTime", required = false) String endTime,
                                            HttpServletResponse response) {
        // 全量导出，限制100w
        limit = "1000000";
        Map<String, String> paramMap = getGeneralParamMap(limit, offset, uid, startTime, endTime);
        if (userName != null){
            paramMap.put("user_name", userName);
        }
        if(sex != null){
            paramMap.put("sex", sex);
        }
        if(category != null){
            paramMap.put("category", category);
        }
        if(mainFlag != null){
            paramMap.put("main_flag", mainFlag);
        }
        if(openFlag != null){
            paramMap.put("open_flag", openFlag);
        }
        if(skillId != null){
            paramMap.put("skill_id", skillId);
        }
        if(forbidFlag != null){
            paramMap.put("forbid_flag", forbidFlag);
        }

        skillService.listUserSkillAdminExport(paramMap, response);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    @RequiresPermissions("godList:view")
    @GetMapping("/god")
    @ExportExcel(itemCls = GodAdminExportDTO.class, listKey = "god_admin_list",
        stateFields = {
            @StateField(key="sex", states = {
                @State(state="0", display = "女"),
                @State(state = "1", display = "男")
            }),
                @StateField(key="state", states = {
                        @State(state="0", display = "已认证"),
                        @State(state="1", display = "禁止认证"),
                        @State(state="2", display = "永久禁止认证"),
                }),
                @StateField(key="openFlag", states = {
                        @State(state="0", display = "关闭接单"),
                        @State(state="1", display = "开启接单"),
                }),
                @StateField(key="topType", states = {
                        @State(state="0", display = "否"),
                        @State(state="1", display = "是")
                }),
                @StateField(key="forbidFlag", states = {
                        @State(state="0", display = "未禁止"),
                        @State(state="1", display = "已禁止")
                })
        },
            unitFields = {
                @UnitField(key="revenue", unit = 100),
            }

    )
    public BaseRsp listGodAdmin(@RequestParam(value = "limit", required = false, defaultValue = "20") String limit,
                                @RequestParam(value = "offset", required = false, defaultValue = "0") String offset,
                                @RequestParam(value = "uid", required = false) String uid,
                                @RequestParam(value = "user_name", required = false) String userName,
                                @RequestParam(value = "query", required = false) String query,
                                @RequestParam(value = "sex", required = false) String sex,
                                @RequestParam(value = "restrict_state", required = false) Integer restrictState,
                                @RequestParam(value = "open_flag", required = false) String openFlag,
                                @RequestParam(value = "startTime", required = false) String startTime,
                                @RequestParam(value = "endTime", required = false) String endTime,
                                @RequestParam(value = "top_type", required = false) String toTypes,
                                @RequestParam(value = "label", required = false) String labels) {
        Map<String, String> paramMap = getGeneralParamMap(limit, offset, uid, startTime, endTime);
        if (userName != null){
            paramMap.put("user_name", userName);
        }
        if (query != null){
            paramMap.put("query", query);
        }
        if(sex != null){
            paramMap.put("sex", sex);
        }
        if(StringUtils.isNotEmpty(toTypes)){
            paramMap.put("top_type",toTypes);
        }
        if(StringUtils.isNotEmpty(labels)){
            paramMap.put("label",labels);
        }
        setForbidFlagOrStateByRestrictState(paramMap, restrictState);
        if(openFlag != null){
            paramMap.put("open_flag", openFlag);
        }
        return skillService.listGodAdmin(paramMap);
    }

    @PostMapping("/update")
    public BaseRsp updateGodAdmin(@RequestBody SkillGodUpdateAdminDTO dto) {
        return skillService.updateGodAdmin(dto);
    }

    @RequestMapping(value = "/god/export", method = RequestMethod.POST)
    public BaseRsp listGodAdminExport(@RequestParam(value = "limit", required = false, defaultValue = "20") String limit,
                                      @RequestParam(value = "offset", required = false, defaultValue = "0") String offset,
                                      @RequestParam(value = "uid", required = false) String uid,
                                      @RequestParam(value = "user_name", required = false) String userName,
                                      @RequestParam(value = "query", required = false) String query,
                                      @RequestParam(value = "sex", required = false) String sex,
                                      @RequestParam(value = "restrict_state", required = false) Integer restrictState,
                                      @RequestParam(value = "open_flag", required = false) String openFlag,
                                      @RequestParam(value = "startTime", required = false) String startTime,
                                      @RequestParam(value = "endTime", required = false) String endTime,
                                      @RequestParam(value = "top_type", required = false) String toTypes,
                                      @RequestParam(value = "label", required = false) String labels,
                                      HttpServletResponse response) {
        // 全量导出，限制100w
        limit = "1000000";
        Map<String, String> paramMap = getGeneralParamMap(limit, offset, uid, startTime, endTime);
        if (userName != null) {
            paramMap.put("user_name", userName);
        }
        if (query != null) {
            paramMap.put("query", query);
        }
        if(sex != null) {
            paramMap.put("sex", sex);
        }
        setForbidFlagOrStateByRestrictState(paramMap, restrictState);
        if(openFlag != null){
            paramMap.put("open_flag", openFlag);
        }
        if(StringUtils.isNotEmpty(toTypes)){
            paramMap.put("top_type",toTypes);
        }
        if(StringUtils.isNotEmpty(labels)){
            paramMap.put("label",labels);
        }
        skillService.listGodAdminExport(paramMap, response);
        return new BaseRsp(ResultEnum.SUCCESS);
    }

    @RequiresPermissions("forbiddenSkillOrGodList:view")
    @GetMapping("/forbid")
    public BaseRsp listSkillForbiddenAdmin(@RequestParam(value = "limit", required = false, defaultValue = "20") String limit,
                                           @RequestParam(value = "offset", required = false, defaultValue = "0") String offset,
                                           @RequestParam(value = "uid", required = false) String uid,
                                           @RequestParam(value = "forbid_type", required = false) String forbidType,
                                           @RequestParam(value = "restrict_state", required = false) Integer restrictState,
                                           @RequestParam(value = "startTime", required = false) String startTime,
                                           @RequestParam(value = "endTime", required = false) String endTime){
        Map<String, String> paramMap = getGeneralParamMap(limit, offset, uid, startTime, endTime);
        if(forbidType != null){
            paramMap.put("forbid_type", forbidType);
        }
        setForbidFlagOrStateByRestrictState(paramMap, restrictState);
        return skillService.listSkillForbiddenAdmin(paramMap);
    }

    @PutMapping("/forbid")
    public BaseRsp updateSkillForbiddenAdmin(@RequestBody SkillForbiddenAdminUpdateDTO updateDTO){
        return skillService.updateSkillForbiddenAdmin(updateDTO);
    }

    @RequiresPermissions("expertsRecommend:view")
    @GetMapping("/recommend")
    public BaseRsp listGodRecommendAdmin(GodRecommendAdminQueryDTO dto){
        Map<String, String> paramMap = getGeneralParamMap(dto.getLimit().toString(), dto.getOffset().toString(), dto.getUid(), null, null);
        if (dto.getUserName() != null){
            paramMap.put("user_name", dto.getUserName());
        }
        return skillService.listGodRecommendAdminByConditions(paramMap);
    }

    @PostMapping("/recommend")
    public BaseRsp addGodRecommendAdmin(@RequestBody GodRecommendAdminAddDTO dto){
        return skillService.addGodRecommendAdmin(dto);
    }

    @PutMapping("/recommend")
    public BaseRsp updateGodRecommendAdmin(@RequestBody GodRecommendAdminUpdateDTO dto){
        return skillService.updateGodRecommendAdmin(dto);
    }

    private Map<String, String> getGeneralParamMap(String limit, String offset, String uid, String startTime, String endTime){
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("limit", limit);
        paramMap.put("offset", offset);
        if(uid != null){
            paramMap.put("uid", uid);
        }
        if(startTime != null){
            paramMap.put("start_time", startTime);
        }
        if(endTime != null){
            paramMap.put("end_time", endTime);
        }
        return paramMap;
    }

    private void setForbidFlagOrStateByRestrictState(Map<String, String> paramMap, Integer restrictState){
        if (restrictState != null){
            GodRestrictStateEnum restrictStateEnum = GodRestrictStateEnum.getGodRestrictStateEnumByRestrictState(restrictState);
            if (authCategory.equals(restrictStateEnum.getForbidCategory())) {
                GodStateEnum state = GodRestrictStateEnum.getGodStateEnumByGodRestrictState(restrictStateEnum);
                if (state != null) {
                    paramMap.put("state", state.getGodState().toString());
                }
            }
            if (orderCategory.equals(restrictStateEnum.getForbidCategory())){
                SkillForbidFlagEnum forbidFlag = GodRestrictStateEnum.getSkillForbidFlagEnumByGodRestrictState(restrictState);
                if(forbidFlag != null){
                    paramMap.put("forbid_flag", forbidFlag.getForbidFlag().toString());
                }
            }
        }
    }

    @PutMapping("/price")
    public BaseRsp batchSetSkillPricesAdmin(@RequestBody UserSkillPriceUpdateDTO dto){
        return skillService.batchSetSkillPricesAdmin(dto.getUid(), dto.getSkillId(), dto.getPrices(), dto.getOrderCount());
    }

    @GetMapping("/price")
    public BaseRsp getSkillPriceAdmin(@RequestParam(value = "uid") Long uid,
                                      @RequestParam(value = "skill_id") Integer skillId){
        return skillService.getSkillPriceAdmin(uid,skillId);
    }
}
